package com.train.quartz.handler;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import com.train.batch.enums.impl.JobOperationEnums;
import com.train.batch.event.JobSyncEvent;
import com.train.common.enums.impl.BizExceptionEnums;
import com.train.common.utils.spring.SpringUtils;
import com.train.quartz.constants.ParamMapConstants;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.scheduling.quartz.QuartzJobBean;

@Slf4j
@DisallowConcurrentExecution //同步执行
@PersistJobDataAfterExecution //对jobDetail实例进行参数持久化处理
public class JobHandler extends QuartzJobBean {

    @Resource
    private ApplicationEventPublisher eventPublisher;

    @SneakyThrows
    @Override
    protected void executeInternal(JobExecutionContext context) {
        //获取job参数
        JobDataMap mergedJobDataMap = context.getMergedJobDataMap();
        String jobName = mergedJobDataMap.getString(ParamMapConstants.JOB_NAME);
        String groupName = mergedJobDataMap.getString(ParamMapConstants.GROUP_NAME);
        if (StrUtil.isEmpty(groupName)) {
            groupName = context.getTrigger().getJobKey().getGroup();
        }
        String jobParam = mergedJobDataMap.getString(ParamMapConstants.JOB_PARAM);
        String retryCount = mergedJobDataMap.getString(ParamMapConstants.RETRY_COUNT);
        String jobInterval = mergedJobDataMap.getString(ParamMapConstants.JOB_INTERVAL);

        //调用Myjob接口执行任务
        try {
            if (StrUtil.isBlank(jobName)) {
                Assert.isNull(jobName, BizExceptionEnums.EXP_JOB_NAME_EMPTY.getMessage());
            }
            MyJob myJob = SpringUtils.getBean(jobName, MyJob.class);
            //执行接口任务
            myJob.execute(jobParam);

            //更新执行时间
            eventPublisher.publishEvent(new JobSyncEvent(this, jobName, groupName, JobOperationEnums.COMPLETE_JOB));
        } catch (Exception e) {
            //异常处理
            expHandler(e, jobName, groupName, retryCount, jobInterval, context.getRefireCount(), context.getScheduler());
        }
    }

    private void expHandler(Exception e, String jobName, String groupName, String retryCount, String jobInterval, int refireCount, Scheduler scheduler) throws SchedulerException {
        //大于指定重试次数或者重试次数为0就抛出异常
        if (refireCount >= Integer.parseInt(retryCount)) {
            //TODO 记录日志

            //删除任务
            scheduler.pauseJob(new JobKey(jobName, groupName));

            //控制台抛出异常信息
            throw new JobExecutionException(e);
        } else {
            //执行间隔
            int interval =  Integer.parseInt(jobInterval);
            if (interval > 0) {
                ThreadUtil.sleep(interval);
            }

            // 更新执行状态
            eventPublisher.publishEvent(new JobSyncEvent(this, jobName, groupName, JobOperationEnums.ERROR_JOB));

            //立刻重试
            throw new JobExecutionException(e, true);
        }
    }
}
